// Kony

#pragma once

#include "CoreMinimal.h"
#include "AbilitySystemInterface.h"
#include "GameFramework/PlayerState.h"
#include "BasePlayerState.generated.h"

//玩家经验值改变时像所有绑定的委托广播
DECLARE_MULTICAST_DELEGATE_OneParam(FOnPlayerStatChanged, int32 /*StatValue*/)
//广播玩家等级变化委托 布尔值是用来区分是升级了还是读取存档设置等级（用于区分是否显示特效和声音）
DECLARE_MULTICAST_DELEGATE_TwoParams(FOnLevelChanged, int32 /*LevelValue*/, bool /*bLevelUp*/)
// 灵气值变化委托
//DECLARE_MULTICAST_DELEGATE_OneParam(FOnLingQiChanged, int32);

// 修为变化委托（如果需要更多信息）
DECLARE_MULTICAST_DELEGATE_ThreeParams(FOnCultivationChanged, int32 /*Cultivation*/, int32 /*Tier*/, int32 /*Stage*/);

//选中目标改变委托 传递新目标和旧目标
DECLARE_MULTICAST_DELEGATE_TwoParams(FOnSelectedTargetChanged, AActor* /*NewTarget*/, AActor* /*OldTarget*/);

class UAbilitySystemComponent;
class UAttributeSet;
class UDataTable;

USTRUCT(BlueprintType)
struct FCultivationStageConfig
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString CultivationName;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	int32 Tiers = 1;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	int32 StagesPerTier = 10;
};

/**
 * 玩家属性状态类 用于存放玩家等级和属性数据集
 */
UCLASS()
class GASC_HUANLING_API ABasePlayerState : public APlayerState, public IAbilitySystemInterface
{
	GENERATED_BODY()
public:
	ABasePlayerState();
	//这个函数是 RPC必须进行重写的函数 否则无法复制
	void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const;
	virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
	UAttributeSet* GetAttributeSet() const{return AttributeSet;} //返回属性集
	// //返回升级所需经验值数据资产，这个是用于计算经验值百分比的(是不是用数据资产还是用CT表？)
	// UPROPERTY(EditDefaultsOnly)
	// TObjectPtr<ULevelUpInfo> LevelUpInfo; 
	//等级配置DataTable，用于计算经验值和升级逻辑
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Level")
	TObjectPtr<UDataTable> LevelConfigDataTable; 
	//玩家经验值和灵气改变时 广播委托
	FOnLevelChanged OnLevelChangedDelegate;
	FOnPlayerStatChanged OnXPChangedDelegate;
	FOnPlayerStatChanged OnLingQiChangedDelegate;
	FOnCultivationChanged OnCultivationChangedDelegate;
	FOnPlayerStatChanged OnXPRequiredForNextLevelDelegate;
	FOnPlayerStatChanged OnAttributePointsChangedDelegate;
	FOnPlayerStatChanged OnSpellPointsChangedDelegate;
	FOnSelectedTargetChanged OnSelectedTargetChangedDelegate;
	//获取玩家等级
	FORCEINLINE int32 GetPlayerLevel() const { return Level; }
	FORCEINLINE int32 GetXP() const { return XP; }
	FORCEINLINE int32 GetLingQi() const { return LingQi; }
	FORCEINLINE int32 GetPlayerCultivation() const { return Cultivation; }
	FORCEINLINE int32 GetPlayerCultivationTier() const { return CultivationTier; }
	FORCEINLINE int32 GetPlayerCultivationStage() const { return CultivationStage; }
	//获取当前等级升级所需经验值（缓存值）
	FORCEINLINE int32 GetXPRequiredForNextLevel() const { return XPRequiredForNextLevel; }
	FORCEINLINE int32 GetAttributePoints() const { return AttributePoints; }
	FORCEINLINE int32 GetSpellPoints() const { return SpellPoints; }
	FORCEINLINE AActor* GetSelectedTarget() const { return SelectedTarget; }
	
	//设置当前等级升级所需经验值（缓存值）
	void SetXPRequiredForNextLevel(int32 InXPRequired); //当前等级升级所需经验值
	void AddToLevel(int32 InLevel); //添加玩家等级
	void AddToXP(int32 InXP); //添加经验值
	void AddToLingQi(int32 InLingQi); //添加灵气
	void AddToCultivation(int32 InCultivation); //添加境界
	void AddToCultivationTier(int32 InCultivationTier); //添加境界层数
	void AddToCultivationStage(int32 InCultivationStage); //添加境界层数小阶段
	void AddToAttributePoints(int32 InAttributePoints); //添加属性点
	void AddToSpellPoints(int32 InSpellPoints); //添加法术点

	
	void SetLevel(int32 InLevel, bool bLevelUp = false); //设置玩家等级，布尔值是用于是否播放升级音效，默认不播放
	void SetXP(int32 InXP); //设置经验值
	void SetLingQi(int32 InLingQi); //设置灵气
	// void SetCultivation(int32 InCultivation);
	// void SetCultivationTier(int32 InCultivationTier);
	// void SetCultivationStage(int32 InCultivationStage);
	void SetAttributePoints(int32 InAttributePoints);
	void SetSpellPoints(int32 InSpellPoints);
	void SetSelectedTarget(AActor* InSelectedTarget); //设置选中目标
	//通过总等级计算获取玩家修为
	void UpdateCultivationFromLevel(); 

protected:
	//玩家能力系统组件
	UPROPERTY(VisibleAnywhere)
	TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;
	//玩家属性集
	UPROPERTY()
	TObjectPtr<UAttributeSet> AttributeSet;
	// 修为配置数组，可在构造函数中初始化
	UPROPERTY(EditDefaultsOnly, Category = "Cultivation")
	TArray<FCultivationStageConfig> CultivationConfigs;

private:
	//选中的目标
	UPROPERTY(VisibleAnywhere,ReplicatedUsing=OnRep_SelectedTarget)
	TObjectPtr<AActor> SelectedTarget;
	//玩家总等级 这个不显示到界面
	UPROPERTY(VisibleAnywhere,ReplicatedUsing=OnRep_Level)
	int32 Level = 1;
	//经验值 修为值
	UPROPERTY(VisibleAnywhere,ReplicatedUsing=OnRep_XP)
	int32 XP = 1;
	//灵气值 用于转换修为或者修炼法术等级
	UPROPERTY(VisibleAnywhere,ReplicatedUsing=OnRep_LingQi)
	int32 LingQi = 1;
	//修为通过总等级计算而来
	//玩家修为、凡人、练气层、筑基、金丹、元婴 等 
	UPROPERTY(VisibleAnywhere,ReplicatedUsing=OnRep_Cultivation)
	int32 Cultivation = 0;
	//玩家修为当前层数、凡人、练气1-13层、筑基9层、金丹9层、元婴9层 等
	UPROPERTY(VisibleAnywhere,ReplicatedUsing=OnRep_CultivationTier)
	int32 CultivationTier = 0;
	//当前修为小等级：每个境界 1~10级 这个是循环的 只有1-10级 例如练气1层10阶
	UPROPERTY(VisibleAnywhere,ReplicatedUsing=OnRep_CultivationStage)
	int32 CultivationStage = 1;
	//缓存当前等级升级所需经验值，避免重复查询DataTable
	UPROPERTY(VisibleAnywhere,ReplicatedUsing=OnRep_XPRequiredForNextLevel)
	int32 XPRequiredForNextLevel = 0;

	//属性点/修为点
	UPROPERTY(VisibleAnywhere,ReplicatedUsing=OnRep_AttributePoints)
	int32 AttributePoints = 0;
	//法术点/修炼点
	UPROPERTY(VisibleAnywhere,ReplicatedUsing=OnRep_SpellPoints)
	int32 SpellPoints = 0;
	
	
	//复制通知
	UFUNCTION()
	void OnRep_SelectedTarget(AActor* OldSelectedTarget);
	UFUNCTION()
	void OnRep_Level(int32 OldLevel);
	UFUNCTION()
	void OnRep_XP(int32 OldXP);
	UFUNCTION()
	void OnRep_LingQi(int32 OldLingQi);
	UFUNCTION()
	void OnRep_Cultivation(int32 OldCultivation);
	UFUNCTION()
	void OnRep_CultivationTier(int32 OldCultivationTier);
	UFUNCTION()
	void OnRep_CultivationStage(int32 OldCultivationStage);
	UFUNCTION()
	void OnRep_XPRequiredForNextLevel(int32 OldXPRequired);
	UFUNCTION()
	void OnRep_AttributePoints(int32 OldAttributePoints);
	UFUNCTION()
	void OnRep_SpellPoints(int32 OldSpellPoints);
	
};


